package org.wheel.plugins.toolkit.sql.render;

import org.wheel.plugins.toolkit.sql.core.AbstractWrapper;
import org.wheel.plugins.toolkit.sql.core.SqlSegment;
import org.wheel.plugins.toolkit.sql.enums.Dialect;
import org.wheel.plugins.toolkit.sql.helper.ParamBank;
import org.wheel.plugins.toolkit.sql.segment.SegmentTree;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * 内部持有 List<SetItem> 完成 SET 拼接 & 参数落库
 * 轻量级 UPDATE 渲染器
 * 只拼出：
 *   UPDATE <table> [[AS] alias]
 *   SET col1 = :p1, col2 = :p2 ...
 *   [WHERE ...]
 *
 * 方言扩展预留：
 *   后期支持 MySQL 的 UPDATE ... JOIN 或 PostgreSQL 的 UPDATE ... FROM
 *   在本类追加分支即可
 */
public class UpdateSqlRenderer {

    private final Dialect dialect;
    private final List<SetItem> setList = new ArrayList<>();

    public UpdateSqlRenderer(Dialect dialect) {
        this.dialect = dialect;
    }

    /* ---------- 对外 ADD 接口 ---------- */
    public void addColumnValue(SqlSegment col, Object value, AbstractWrapper<?, ?> wrapper) {
        String key = wrapper.getContext().getParamBank().nextParam(value);
        setList.add(new SetItem(col.getSql() + " = :" + key, value));
    }

    public void addColumnSql(SqlSegment col, String rawSql) {
        setList.add(new SetItem(col.getSql() + " = " + rawSql, null));
    }

    public void addRawSql(String rawSql) {
        setList.add(new SetItem(rawSql, null));
    }

    /* ---------- 渲染 ---------- */
    public String render(SegmentTree tree, ParamBank bank) {
        if (setList.isEmpty()) throw new IllegalStateException("UPDATE 必须至少一个 SET 项");
        StringBuilder sql = new StringBuilder();
        /* 1. UPDATE */
        sql.append("UPDATE ").append(tree.getMainTable());
        if (tree.getMainAlias() != null) sql.append(" ").append(tree.getMainAlias());
        /* 2. SET */
        sql.append(" SET ");
        for (int i = 0; i < setList.size(); i++) {
            if (i > 0) sql.append(", ");
            sql.append(setList.get(i).sql);
        }
        /* 3. WHERE */
        Optional<String> where = tree.buildWhereSql();
        where.ifPresent(w -> sql.append(" WHERE ").append(w));
        return sql.toString();
    }

    /* 内部记录 SET 片段 & 参数值（参数已落库，这里仅调试用） */
    private record SetItem(String sql, Object value) {}
}